home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 44 / PC Actual CD 44.iso / Linux / Cygwin / full.exe / Disk1 / data1.cab / Tools / share / tix4.1 / fs.tcl < prev    next >
Encoding:
Text File  |  1998-12-04  |  11.4 KB  |  645 lines

  1. # tixAssert --
  2. #
  3. #    Debugging routine. Evaluates the test script in the context of the
  4. #    caller. The test script is responsible for generating the error.
  5. #    
  6. proc tixAssert {script} {
  7.     uplevel $script
  8. }
  9.  
  10. proc tixAssertNorm {path} {
  11.     if ![tixFSIsNorm $path] {
  12.     error "\"$path\" is not a normalized path"
  13.     }
  14. }
  15.  
  16. proc tixAssertVPath {vpath} {
  17.     if ![tixFSIsVPath $vpath] {
  18.     error "\"$vpath\" is not a VPATH"
  19.     }
  20. }
  21.  
  22. # tixFSAbsPath --
  23. #
  24. #    Converts $path into an normalized absolute path
  25. #
  26. proc tixFSAbsPath {path} {
  27.     return [lindex [tixFSNorm [tixFSVPWD] $path] 0]
  28. }
  29.  
  30. # tixFSVPWD --
  31. #
  32. #    Returns the VPATH of the current directory.
  33. #
  34. proc tixFSVPWD {} {
  35.     return [tixFSVPath [tixFSPWD]]
  36. }
  37.  
  38. if {![info exists tcl_platform] || $tcl_platform(platform) == "unix"} {
  39.  
  40. # tixFSPWD --
  41. #
  42. #    Return the current directory
  43. #
  44. proc tixFSPWD {} {
  45.     return [pwd]
  46. }
  47.  
  48. # tixFSDisplayName --
  49. #
  50. #    Returns the name of a normalized path which is usually displayed by
  51. #    the OS
  52. #
  53. proc tixFSDisplayName {normpath} {
  54.     tixAssert {
  55.     tixAssertNorm $normpath
  56.     }
  57.     return $normpath
  58. }
  59.  
  60. proc tixFSIsAbsPath {path} {
  61.     return [tixStrEq [string index $path 0] /]
  62. }
  63.  
  64. # tixFSIsNorm_os --
  65. #
  66. #    Returns true iff this pathname is normalized, in the OS native name
  67. #    format
  68. #
  69. proc tixFSIsNorm_os {path} {
  70.     return [tixFSIsNorm $path]
  71. }
  72.  
  73. proc tixFSIsNorm {path} {
  74.     if [tixStrEq $path /] {
  75.     return 1
  76.     }
  77.  
  78.     # relative path
  79.     #
  80.     if ![regexp {^/} $path] {
  81.     return 0
  82.     }
  83.  
  84.     if [regexp {/[.]$} $path] {
  85.     return 0
  86.     }
  87.     if [regexp {/[.][.]$} $path] {
  88.     return 0
  89.     }
  90.     if [regexp {/[.]/} $path] {
  91.     return 0
  92.     }
  93.     if [regexp {/[.][.]/} $path] {
  94.     return 0
  95.     }
  96.     if [tixStrEq $path .] {
  97.     return 0
  98.     }
  99.     if [tixStrEq $path ..] {
  100.     return 0
  101.     }
  102.  
  103.     # Tilde
  104.     #
  105.     if [regexp {^~} $path] {
  106.     return 0
  107.     }
  108.  
  109.     # Double slashes
  110.     #
  111.     if [regexp {//} $path] {
  112.     return 0
  113.     }
  114.  
  115.     # Trailing slashes
  116.     #
  117.     if [regexp {/$} $path] {
  118.     return 0
  119.     }
  120.  
  121.     return 1
  122. }
  123.  
  124. # tixFSIsValid --
  125. #
  126. #    Checks whether a native pathname contains invalid characters.
  127. #
  128. proc tixFSIsValid {path} {
  129.     return 1
  130. }
  131.  
  132. proc tixFSIsVPath {vpath} {
  133.     return [tixFSIsNorm $vpath]
  134. }
  135.  
  136. # tixFSVPath --
  137. #
  138. #    Converts a native pathname to its VPATH
  139. #
  140. proc tixFSVPath {path} {
  141.     tixAssert {
  142.     tixAssertNorm $path
  143.     }
  144.     return $path
  145. }
  146.  
  147. # tixFSPath --
  148. #
  149. #    Converts a vpath to a native pathname
  150. proc tixFSPath {vpath} {
  151.     tixAssert {
  152.     tixAssertVPath $vpath
  153.     }
  154.     return $vpath
  155. }
  156.  
  157. # tixFSTildeSubst -- [Unix only]
  158. #
  159. #    Substitutes any leading tilde characters if possible. No error is
  160. #    generated if the user doesn't exist.
  161. #
  162. proc tixFSTildeSubst {text} {
  163.     if [tixStrEq [string index $text 0] ~] {
  164.     # The following will report if the user doesn't exist
  165.     if [catch {
  166.         file isdir $text
  167.     }] {
  168.         return ./$text
  169.     }
  170.     return [tixFile tilde $text]
  171.     } else {
  172.     return $text
  173.     }
  174. }
  175.  
  176. # tixFSNorm --
  177. #
  178. #    Interprets the user's input and return file information about this
  179. #    input.
  180. #
  181. # Arguments:
  182. #    See documentation (docs/Files.txt)
  183. #
  184. proc tixFSNorm {context text {defFile ""} {flagsVar ""} {errorMsgVar ""}} {
  185.     tixAssert {
  186.     tixAssertVPath $context
  187.     }
  188.  
  189.     if ![tixStrEq $errorMsgVar ""] {
  190.     upvar $errorMsgVar errorMsg
  191.     }
  192.     if ![tixStrEq $flagsVar ""] {
  193.     upvar $flagsVar flags
  194.     }
  195.  
  196.     set hasDirSuffix [regexp {/$} $text]
  197.     set text [tixFSTildeSubst $text]
  198.     set text [_tixJoin $context $text]
  199.  
  200.     if {$hasDirSuffix || [file isdir $text]} {
  201.     set dir $text
  202.     set tail $defFile
  203.     } else {
  204.     set dir [file dirname $text]
  205.     set tail [file tail $text]
  206.     }
  207.  
  208.     set norm $dir/$tail
  209.     regsub -all /+ $norm / norm
  210.     if ![tixStrEq $norm /] {
  211.     regsub {/$} $norm "" norm
  212.     }
  213.  
  214.     if ![info exists flag(noPattern)] {
  215.     set isPat 0
  216.     foreach char [split $tail ""] {
  217.         if {$char == "*" || $char == "?"} {
  218.         set isPat 1
  219.         break
  220.         }
  221.     }
  222.     if {$isPat} {
  223.         return [list $norm $dir "" $tail]
  224.     }
  225.     }
  226.  
  227.     return [list $norm $dir $tail ""]
  228. }
  229.  
  230. # _tixJoin -- [Internal]
  231. #    Joins two native pathnames.
  232. #
  233. proc _tixJoin {p1 p2} {
  234.     if [tixStrEq [string index $p2 0] /] {
  235.     return [_tixNormalize $p2]
  236.     } else {
  237.     return [_tixNormalize $p1/$p2]
  238.     }
  239. }
  240.  
  241. # tixFSNormDir --
  242. #
  243. #    Normalizes an absolute path.
  244. #
  245. proc tixFSNormDir {dir} {
  246.     set dir [tixFile tilde $dir]
  247.     if ![tixStrEq [string index $dir 0] /] {
  248.     error "\"$dir\" must be an absolute pathname"
  249.     }
  250.     if ![file isdir $dir] {
  251.     error "\"$dir\" is not a directory"
  252.     }
  253.     return [_tixNormalize $dir]
  254. }
  255.  
  256. # _tixNormalize --
  257. #
  258. #    Normalizes an absolute pathname.
  259. #
  260. #     $dir must be an absolute pathname
  261. #
  262. proc _tixNormalize {path} {
  263.     tixAssert {
  264.     if ![tixStrEq [string index $path 0] /] {
  265.         error "\"$path\" must be an absolute pathname"
  266.     }
  267.     }
  268.  
  269.     # Don't be fooled: $path doesn't need to be a directory. The following
  270.     # code just makes it easy to get rid of trailing . and ..
  271.     #
  272.     set path $path/
  273.     regsub -all /+ $path / path
  274.     while 1 {
  275.     if ![regsub {/\./} $path "/" path] break
  276.     }
  277.     while 1 {
  278.     if ![regsub {/\.$} $path "" path] break
  279.     }
  280.  
  281.     while 1 {
  282.     if ![regsub {/[^/]+/\.\./} $path "/" path] break
  283.     while 1 {
  284.         if ![regsub {^/\.\./} $path "/" path] break
  285.     }
  286.     }
  287.     while 1 {
  288.     if ![regsub {^/\.\./} $path "/" path] break
  289.     }
  290.  
  291.     regsub {/$} $path "" path
  292.     if [tixStrEq $path ""] {
  293.     return /
  294.     } else {
  295.     return $path
  296.     }
  297. }
  298.  
  299. # tixFSCreateDirs
  300. #
  301. #
  302. proc tixFSCreateDirs {path} {
  303.     tixAssert {
  304.     error "Procedure tixFSCreateDirs not implemented on all platforms"
  305.     }
  306.     if [tixStrEq $path /] {
  307.     return 1
  308.     }
  309.     if [file exists $path] {
  310.     return 1
  311.     }
  312.     if ![tixFSCreateDirs [file dirname $path]] {
  313.     return 0
  314.     }
  315.     if [catch {exec mkdir $path}] {
  316.     return 0
  317.     }
  318.     return 1
  319. }
  320.  
  321. } else {
  322.  
  323. #-Win--------------------------------------------------------------------
  324.  
  325. # (Win) tixFSPWD --
  326. #
  327. #    Return the current directory
  328. #
  329. proc tixFSPWD {} {
  330.     set p [pwd]
  331.     regsub -all / $p \\ p
  332.     return $p
  333. }
  334. # Win
  335. #
  336. proc tixFSIsNorm {path} {
  337.  
  338.     # Drive root directory
  339.     # CYGNUS LOCAL: drive can be immediately followed by directory separator.
  340.     #
  341.     if [regexp {^[A-z]:\\?$} $path] {
  342.     return 1
  343.     }
  344.  
  345.     # If it is not a drive root directory, it must
  346.     # have a leading [drive letter:]\\[non empty string]
  347.     # CYGNUS LOCAL: A UNC path (\\host\dir) is also OK.
  348.     if ![regexp {^[A-z]:\\.} $path] {
  349.     if ![regexp {^\\\\.*\\.} $path] {
  350.         return 0
  351.     }
  352.     }
  353.  
  354.     # relative path
  355.     #
  356.     if [regexp {\\[.]$} $path] {
  357.     return 0
  358.     }
  359.     if [regexp {\\[.][.]$} $path] {
  360.     return 0
  361.     }
  362.     if [regexp {\\[.]\\} $path] {
  363.     return 0
  364.     }
  365.     if [regexp {\\[.][.]\\} $path] {
  366.     return 0
  367.     }
  368.     if [tixStrEq $path .] {
  369.     return 0
  370.     }
  371.     if [tixStrEq $path ..] {
  372.     return 0
  373.     }
  374.  
  375.     # Double slashes
  376.     # CYGNUS LOCAL: Double slashes at the front are OK.
  377.     #
  378.     if [regexp {.\\\\} $path] {
  379.     return 0
  380.     }
  381.  
  382.     # Trailing slashes
  383.     #
  384.     if [regexp {[\\]$} $path] {
  385.     return 0
  386.     }
  387.  
  388.     return 1
  389. }
  390.  
  391. # (Win) tixFSNorm --
  392. #
  393. #    Interprets the user's input and return file information about this
  394. #    input.
  395. #
  396. # Arguments:
  397. #    See documentation (docs/Files.txt)
  398. #
  399. proc tixFSNorm {context text {defFile ""} {flagsVar ""} {errorMsgVar ""}} {
  400.     tixAssert {
  401.     tixAssertVPath $context
  402.     }
  403.  
  404.     if ![tixStrEq $errorMsgVar ""] {
  405.     upvar $errorMsgVar errorMsg
  406.     }
  407.     if ![tixStrEq $flagsVar ""] {
  408.     upvar $flagsVar flags
  409.     }
  410.  
  411.     set isDir [regexp {[\\]$} $text]
  412.     set text [_tixJoin $context $text]
  413.     set path [tixFSPath $text]
  414.  
  415.     if {$isDir || [file isdir $path]} {
  416.     set vpath $text
  417.     set tail $defFile
  418.     } else {
  419.     set list [split $text \\]
  420.     set tail [lindex $list end]
  421.     set len [string length $tail]
  422.     set vpath [string range $text 0 [expr [string len $text]-$len-1]]
  423.     regsub {[\\]$} $vpath "" vpath
  424.     }
  425.  
  426.     set path [tixFSPath $vpath]
  427.  
  428.     if ![info exists flag(noPattern)] {
  429.     set isPat 0
  430.     foreach char [split $tail ""] {
  431.         if {$char == "*" || $char == "?"} {
  432.         set isPat 1
  433.         break
  434.         }
  435.     }
  436.     if {$isPat} {
  437.         return [list $path $vpath "" $tail]
  438.     }
  439.     }
  440.  
  441.     return [list $path $vpath $tail ""]
  442. }
  443.  
  444. # Win
  445. #
  446. # _tixJoin -- [internal]
  447. #
  448. #    Joins a pathname to a VPATH
  449. #
  450. proc _tixJoin {vp1 p2} {
  451.     if [tixFSIsAbsPath $p2] {
  452.     return [tixFSVPath [_tixNormalize $p2]]
  453.     } else {
  454.     return [tixFSVPath [_tixNormalize [tixFSPath $vp1]\\$p2]]
  455.     }
  456. }
  457.  
  458. # (Win) tixFSIsAbsPath
  459. #
  460. #    The Tcl "file pathtype" is buggy. E.g. C:\.\..\. is absolute, but
  461. #    "file pathtype" thinks that it isn't
  462. #
  463.  
  464. proc tixFSIsAbsPath {path} {
  465.     # CYGNUS LOCAL: Handle a UNC path (\\host\dir)
  466.     if [regexp {^\\\\.*\\.} $path] {
  467.     return 1
  468.     }
  469.     return [regexp {^[A-z]:\\} $path]
  470. }
  471.  
  472. # (Win) tixFSIsNorm_os
  473. #
  474. #    Returns true iff this pathname is normalized, in the OS native name
  475. #    format
  476. #
  477. proc tixFSIsNorm_os {path} {
  478.     if [regexp {^[A-z]:[\\]$} $path] {
  479.     return 1
  480.     }
  481.     if [regexp {^[A-z]:$} $path] {
  482.     return 0
  483.     }
  484.  
  485.     return [tixFSIsNorm $path]
  486.  
  487. }
  488.  
  489. # Win
  490. #
  491. # _tixNormalize --
  492. #
  493. #    Normalizes an absolute pathname.
  494. #
  495. #     $dir must be an absolute native pathname
  496. #
  497. proc _tixNormalize {abpath} {
  498.     tixAssert {
  499.     if ![tixFSIsAbsPath $abpath] {
  500.         error "\"$abpath\" must be an absolute pathname"
  501.     }
  502.     }
  503.  
  504.     # CYGNUS LOCAL: Handle UNC paths (\\host\dir)
  505.     if [regexp {^\\\\.*\\.} $abpath] {
  506.     set drive "\\"
  507.     regsub {^\\} $abpath "" path
  508.     } else {
  509.     if ![regexp {^[A-z]:} $abpath drive] {
  510.         tixPanic "\"$abpath\" does not contain a drive letter"
  511.     }
  512.     set drive [string toupper $drive]
  513.  
  514.     regsub {^[A-z]:} $abpath "" path
  515.     }
  516.  
  517.     # Don't be fooled: $path doesn't need to be a directory. The following
  518.     # code "set path $path\\" just makes it easy to get rid of trailing
  519.     # . and ..
  520.     #
  521.     set path $path\\
  522.     regsub -all {[\\]+} $path \\ path
  523.     while 1 {
  524.     if ![regsub {\\[.]\\} $path "\\" path] break
  525.     }
  526.     while 1 {
  527.     if ![regsub {\\[.]$} $path "" path] break
  528.     }
  529.  
  530.     while 1 {
  531.     if ![regsub {\\[^\\]+\\[.][.]\\} $path "\\" path] break
  532.     while 1 {
  533.         if ![regsub {^\\[.][.]\\} $path "\\" path] break
  534.     }
  535.     }
  536.     while 1 {
  537.     if ![regsub {^\\[.][.]\\} $path "\\" path] break
  538.     }
  539.  
  540.     regsub {[\\]+$} $path "" path
  541.     return $drive$path
  542. }
  543.  
  544. # Win
  545. #
  546. # tixFSNormDir --
  547. #
  548. #    Normalizes a directory
  549. #
  550. proc tixFSNormDir {dir} {
  551.     if ![tixFSIsAbsPath $dir] {
  552.     error "\"$dir\" must be an absolute pathname"
  553.     }
  554.     if ![file isdir $dir] {
  555.     error "\"$dir\" is not a directory"
  556.     }
  557.     return [_tixNormalize $dir]
  558. }
  559.  
  560.  
  561. proc tixPanic {message} {
  562.     error $message
  563. }
  564.  
  565. # tixFSIsValid --
  566. #
  567. #    Checks whether a native pathname contains invalid characters.
  568. #
  569. proc tixFSIsValid {path} {
  570.     return 1
  571. }
  572.  
  573. # Win
  574. #
  575. #
  576. proc tixFSIsVPath {vpath} {
  577.     global tixPriv
  578.     if $tixPriv(isWin95) {
  579.     # CYGNUS LOCAL: Accept UNC path (\\host\dir)
  580.     if [string match {xx\\xx\\\\\\*\\*} $vpath] {
  581.         return 1
  582.     }
  583.     return [string match {xx\\xx\\[A-z]:*} $vpath]
  584.     } else {
  585.     return [string match {xx\\[A-z]:*} $vpath]
  586.     }
  587. }
  588.  
  589. # Win
  590. #
  591. # tixFSVPath --
  592. #
  593. #    Converts a normalized native pathname to its VPATH
  594. #
  595. proc tixFSVPath {path} {
  596.     global tixPriv
  597.  
  598.     tixAssert {
  599.     tixAssertNorm $path
  600.     }
  601.     return $tixPriv(WinPrefix)\\$path
  602. }
  603.  
  604. # tixFSPath --
  605. #
  606. #    Converts a vpath to a native pathname
  607. proc tixFSPath {vpath} {
  608.     global tixPriv
  609.     tixAssert {
  610.     tixAssertVPath $vpath
  611.     }
  612.     if $tixPriv(isWin95) {
  613.     set path [string range $vpath 6 end]
  614.     } else {
  615.     set path [string range $vpath 3 end]
  616.     }
  617.     regsub {:$} $path :\\ path
  618.  
  619.     return $path
  620. }
  621.  
  622. # tixFSDisplayName --
  623. #
  624. #    Returns the name of a normalized path which is usually displayed by
  625. #    the OS
  626. #
  627. proc tixFSDisplayName {normpath} {
  628.     tixAssert {
  629.     tixAssertNorm $normpath
  630.     }
  631.  
  632.     if [regexp {^[A-z]:$} $normpath] {
  633.     return $normpath\\
  634.     } else {
  635.     return $normpath
  636.     }
  637. }
  638.  
  639.  
  640. tixInitFileCmpt:Win 
  641.  
  642. }
  643.